package com.shiku.imclient;

import com.shiku.imserver.common.constant.KConstants;
import com.shiku.imserver.common.message.AbstractBaseMessage;
import com.shiku.imserver.common.message.AbstractMessage;
import com.shiku.imserver.common.message.AuthMessage;
import com.shiku.imserver.common.message.ChatMessage;
import com.shiku.imserver.common.message.MessageHead;
import com.shiku.imserver.common.proto.MessageProBuf;
import com.shiku.imserver.common.tcp.TcpPacket;
import com.shiku.imserver.common.utils.Callback;
import com.shiku.imserver.common.utils.ProBufUtils;
import com.shiku.imserver.common.utils.ThreadUtil;
import java.util.Scanner;
import org.tio.client.ClientChannelContext;
import org.tio.client.ClientGroupContext;
import org.tio.client.ReconnConf;
import org.tio.client.TioClient;
import org.tio.client.intf.ClientAioHandler;
import org.tio.client.intf.ClientAioListener;
import org.tio.core.ChannelContext;
import org.tio.core.Node;
import org.tio.core.Tio;
import org.tio.core.intf.Packet;
import org.tio.utils.hutool.StrUtil;

public class IMClientStarter2 {
  static String serverIp = "192.168.0.168";
  
  static int serverPort = 5666;
  
  private static Node serverNode = new Node(serverIp, serverPort);
  
  private static ClientChannelContext context;
  
  public static void processCommand(String line) throws Exception {
    if (StrUtil.isBlank(line))
      return; 
    MessageHead messageHead = new MessageHead();
    ChatMessage message = new ChatMessage();
    messageHead.setChatType((byte)1);
    messageHead.setFrom("20000/Server");
    messageHead.setTo("10000");
    message.setFromUserId("20000");
    message.setFromUserName("20000");
    message.setToUserId("10000");
    message.setToUserName("10000");
    message.setContent(line);
    message.setType((short)1);
    message.setMessageHead(messageHead);
    byte[] bytes = ProBufUtils.encodeMessageBody((AbstractMessage)message, MessageProBuf.ChatMessage.getDescriptor());
    TcpPacket packet = new TcpPacket((short)10, bytes);
    Tio.send((ChannelContext)context, (Packet)packet);
  }
  
  public static void main(String[] args) throws Exception {
    context = getClientChannelContext();
    authUser();
    KConstants.isDebug = false;
    while (true);
  }
  
  public static void authUser() {
    MessageHead messageHead = new MessageHead();
    ChatMessage message = new ChatMessage();
    messageHead.setChatType((byte)1);
    messageHead.setFrom("20000/Server");
    messageHead.setTo("10000");
    message.setFromUserId("20000");
    message.setFromUserName("20000");
    message.setToUserId("10000");
    message.setToUserName("10000");
    message.setContent("1111111");
    message.setType((short)1);
    message.setMessageHead(messageHead);
    AuthMessage authMessage = new AuthMessage();
    authMessage.setPassword("1234567");
    authMessage.setToken("token2");
    authMessage.setMessageHead(messageHead);
    byte[] bytes = ProBufUtils.encodeMessageBody((AbstractMessage)authMessage, MessageProBuf.AuthMessage.getDescriptor());
    TcpPacket packet = new TcpPacket((short)5, bytes);
    Tio.send((ChannelContext)context, (Packet)packet);
  }
  
  public static void whileConnect() {
    for (int i = 0; i < 1000; i++) {
      ThreadUtil.executeInThread(new Callback() {
            public void execute(Object obj) {
              ClientChannelContext context = IMClientStarter2.getClientChannelContext();
            }
          });
    } 
  }
  
  public static ClientGroupContext getClientGroupContext() {
    BaseClientHandler baseClientHandler = new BaseClientHandler() {
        public void handlerReceipt(String messageId) {}
      };
    BaseClientListener baseClientListener = new BaseClientListener() {
        public AuthMessage authUserMessage(ChannelContext channelContext, BaseIMClient imClient) {
          return null;
        }
      };
    ReconnConf reconnConf = new ReconnConf(5000L);
    ClientGroupContext clientGroupContext = new ClientGroupContext((ClientAioHandler)baseClientHandler, (ClientAioListener)baseClientListener, reconnConf);
    return clientGroupContext;
  }
  
  public static ClientChannelContext getClientChannelContext() {
    ClientChannelContext clientChannel = null;
    try {
      ClientGroupContext context = getClientGroupContext();
      clientChannel = (new TioClient(context)).connect(serverNode);
      clientChannel.setHeartbeatTimeout(Long.valueOf(10000L));
    } catch (Exception e) {
      e.printStackTrace();
    } 
    return clientChannel;
  }
  
  public static void whileSendMsg(ClientChannelContext context) {
    int i = 0;
    long start = System.currentTimeMillis();
    int count = 50000;
    for (int j = 0; j < count; j++) {
      MessageHead messageHead = new MessageHead();
      ChatMessage message = new ChatMessage();
      messageHead.setChatType((byte)1);
      messageHead.setFrom("20000/Server");
      messageHead.setTo("10000");
      message.setFromUserId("10000");
      message.setFromUserName("10000");
      message.setToUserId("20000");
      message.setToUserName("20000");
      message.setContent(i + "====>");
      message.setType((short)1);
      message.setMessageHead(messageHead);
      TcpPacket packet = ProBufUtils.encodeTcpPacket((AbstractBaseMessage)message, MessageProBuf.ChatMessage.getDescriptor());
      packet.setCommand((short)10);
      Tio.send((ChannelContext)context, (Packet)packet);
      try {
        Thread.sleep(2L);
      } catch (InterruptedException e) {
        e.printStackTrace();
      } 
      i++;
    } 
    long timeCount = (System.currentTimeMillis() - start) / 1000L;
    System.out.println("  " + count + " " + timeCount + "  " + (count / timeCount));
  }
  
  public static void command() throws Exception {
    Scanner sc = new Scanner(System.in);
    int i = 1;
    StringBuilder sb = new StringBuilder();
    sb.append("\r\n");
    sb.append(i++ + "'?'.\r\n");
    sb.append(i++ + "'login loginname password'.\r\n");
    sb.append(i++ + "'join group1'.\r\n");
    sb.append(i++ + "'groupMsg group1 text'.\r\n");
    sb.append(i++ + "'p2pMsg loginname text'.\r\n");
    sb.append(i++ + "'exit'.\r\n");
    System.out.println(sb);
    String line = sc.nextLine();
    while (true) {
      if ("exit".equalsIgnoreCase(line)) {
        System.out.println("Thanks for using! bye bye.");
        break;
      } 
      if ("?".equals(line))
        System.out.println(sb); 
      processCommand(line);
      line = sc.nextLine();
    } 
    System.exit(0);
  }
}
